package platform

import (
	"context"
	"fmt"
	"io"

	"gitee.com/bjf-fhe/apicat/entry"
	"gitee.com/bjf-fhe/apicat/source"
	"github.com/sirupsen/logrus"
	"github.com/spf13/pflag"
)

//Notifier有两种实现模式，一种是批量，一种是单条，因此Notifier类型作为通用类型，只是interface{}
type Notifier interface {
	ListExistedEntrys() (map[string]*entry.LogEntry, error)
	NotifyDel(...*entry.LogEntry) error
	NotifyAdd(*entry.LogEntry) error
}
type Source interface{}
type Handler interface {
	AddFlags(*pflag.FlagSet)
	GetNotifier(ctx context.Context) (Notifier, error)
	GetSource(fileHandler Configer, ctx context.Context, tailMode bool) (source.Reader, error)
}
type HandlerNeedCheck interface {
	Check(fileHandler Configer) error
}

//Configer 配置来源文件，获取来源文件的属性，获得文件描述符的适配接口
type Configer interface {
	IsLocalFile() bool
	GetFileName() string
	OpenFile() (io.Reader, error)
	GetTimeFormat() string
}

type loadedHandler struct {
	Handler Handler
	inited  bool
}

func (handler *loadedHandler) Init(fileHandler Configer) error {
	if checker, ok := handler.Handler.(HandlerNeedCheck); ok {
		err := checker.Check(fileHandler)
		if err != nil {
			return err
		}
	}
	handler.inited = true
	return nil
}

var handlers = make(map[string]*loadedHandler)

func Register(name string, handler Handler) {
	handlers[name] = &loadedHandler{
		Handler: handler,
	}
}

func GetNotifier(name string, ctx context.Context, platCfg Configer) (Notifier, error) {
	logrus.Debug("加载平台：", name)
	handler, ok := handlers[name]
	if ok {
		if !handler.inited {
			if err := handler.Init(platCfg); err != nil {
				return nil, err
			}
		}
		return handler.Handler.GetNotifier(ctx)
	}
	var names []string
	for k := range handlers {
		names = append(names, k)
	}

	err := fmt.Errorf("指定的Notify终端%s不存在\n已注册的类型包括：%v\n将采用默认处理", name, names)
	logrus.Error(err)
	return nil, err
}

//GetSource 按名称获得并初始化一个指定来源
func GetSource(name string, fileHandler Configer, ctx context.Context, tailMode bool) (source.Reader, error) {
	handler, ok := handlers[name]
	if ok {
		if !handler.inited {
			if err := handler.Init(fileHandler); err != nil {
				return nil, err
			}
		}
		return handler.Handler.GetSource(fileHandler, ctx, tailMode)
	}
	var names []string
	for k := range handlers {
		names = append(names, k)
	}

	return nil, fmt.Errorf("指定的Source%s不存在\n已注册的类型包括：%v\n将采用默认处理", name, names)
}

func AddFlags(set *pflag.FlagSet) {
	for k, v := range handlers {
		var sub = pflag.NewFlagSet(k, pflag.ContinueOnError)
		v.Handler.AddFlags(sub)
		sub.SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
			return pflag.NormalizedName(k + "-" + name)
		})
		set.AddFlagSet(sub)
	}
}
